Skip to content

Fix workspace close shortcut window targeting - #6365

Closed
azooz2003-bit wants to merge 6 commits into
mainfrom
feat-workspace-close-key-window
Closed

azooz2003-bit wants to merge 6 commits into
mainfrom
feat-workspace-close-key-window

Conversation

@azooz2003-bit

@azooz2003-bit azooz2003-bit commented Jun 17, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Route Cmd+Shift+W workspace-close through the event-originating main-window context before app-level active-manager fallback.
  • Keep the confirmation sheet tied to the same target manager/window.
  • Add a multi-window XCUITest that closes from the focused window and verifies the other window remains untouched.

Testing

  • Not run locally, XCUITest must run on hosted macOS per repo policy.

View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Summary by cubic

Fixes Cmd+Shift+W so it closes the selected workspace in the focused main window and anchors the confirmation sheet to that same window. Adds a multi‑window XCUITest with key‑window checks and sturdier control‑socket readiness/client.

  • Bug Fixes
    • Route the close shortcut through key/main/event‑window context and activate the targeted main window; if the event comes from an auxiliary or non‑addressable window, don’t fallback.
    • Keep the confirmation sheet hosted by the targeted window; in DEBUG record closeConfirmationTargetWindowId, closeConfirmationTargetWorkspaceId, closeConfirmationTargetWorkspaceIds, closeConfirmationHostWindowId, closeConfirmationPresentation, and closeConfirmationAttachedSheet for assertions.

Written for commit 556c873. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes

    • Improved Cmd+Shift+W workspace-close shortcut routing. When multiple windows are open, the “Close workspace?” confirmation and close action now reliably target the workspace selected in the focused window.
  • Tests

    • Added a UI test covering multi-window focused-target behavior for the close-workspace confirmation flow.
    • Improved UI test synchronization with the control socket and updated dialog interaction helpers to work with per-workspace confirmation.

@vercel

vercel Bot commented Jun 17, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Jun 21, 2026 3:17am
cmux-staging Building Building Preview, Comment Jun 21, 2026 3:17am

@coderabbitai

coderabbitai Bot commented Jun 17, 2026 •

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

AppDelegate gains two new helpers that resolve the correct MainWindowContext for the Cmd+Shift+W close-workspace shortcut (handling auxiliary windows and fallback ordering) and replace the previous direct tabManager call in the shortcut branch. TabManager adds DEBUG-only UITestRecorder telemetry recording target workspace and host window ids at both close-confirmation initiation and sheet presentation. A new UI test asserts the confirmation targets the focused window's workspace when multiple windows are open.

Changes

Focused-window close-workspace routing and telemetry

Layer / File(s) Summary
AppDelegate: MainWindowContext resolution and shortcut wiring
Sources/AppDelegate.swift
mainWindowContextForFocusedWorkspaceCloseShortcut(event:) resolves the correct context with auxiliary-window nil-return and key→main→active→first fallback. closeWorkspaceFromFocusedShortcut(event:) activates the resolved context and calls closeCurrentWorkspaceWithConfirmation(). The .closeWorkspace shortcut branch is updated to call this new helper.
TabManager: DEBUG UITest telemetry
Sources/TabManager.swift
New private recordCloseConfirmationTarget(workspaceIds:) helper emits target workspace ids and host window id via UITestRecorder. Called on single- and batch-workspace close confirmation initiation; sheet presentation telemetry extended with closeConfirmationHostWindowId.
UI test support: Socket readiness and window parsing
cmuxUITests/CloseWorkspacesConfirmDialogUITests.swift
waitForSocketPong improved to check diagnostics JSON when pong does not resolve. New helpers: requireUUID (extract UUID tokens), waitForKeyWindow/keyWindowId (query focused window), clickCancelOnCloseWorkspaceAlert, closeWorkspaceDialog, closeWorkspaceAlert (interact with per-workspace confirmations).
UI test: Cmd+Shift+W targets focused window's workspace
cmuxUITests/CloseWorkspacesConfirmDialogUITests.swift
New test testCmdShiftWTargetsFocusedWindowWorkspaceWhenMultipleWindowsAreOpen opens two windows with distinct workspaces, focuses the first, triggers the shortcut, asserts via telemetry that confirmation targets the focused window, and dismisses the confirmation via Cancel.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • manaflow-ai/cmux-dev-artifacts#2959: The new UI test testCmdShiftWTargetsFocusedWindowWorkspaceWhenMultipleWindowsAreOpen added in this PR is the test failing in that issue, which reports receiving nil instead of an expected UUID in the initial socket response.
  • manaflow-ai/cmux-dev-artifacts#2958: This PR introduces the test testCmdShiftWTargetsFocusedWindowWorkspaceWhenMultipleWindowsAreOpen that is failing on the feat-workspace-close-key-window branch due to socket communication timing issues.

Possibly related PRs

  • manaflow-ai/cmux#4615: Modifies the same AppDelegate focused-close routing for Cmd+Shift+W so the confirmation targets the currently focused window, with matching shortcut-targeting tests — directly related at the shortcut-routing code level.
  • manaflow-ai/cmux#4406: Both PRs modify Sources/AppDelegate.swift's close-workspace and close-shortcut key-equivalent routing logic in overlapping areas, with this PR changing which MainWindowContext owns the .closeWorkspace action.

Poem

🐇 Hop hop, the shortcut finds its way,
Through auxiliary windows — none shall stray.
The focused pane gets its own close,
While other workspaces keep their prose.
Telemetry records each UUID neat,
A confirmed close, tidy and complete! 🎉


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (3 errors, 2 warnings)

Check name Status Explanation Resolution
Cmux Cache Substitution Correctness ❌ Error recordCloseConfirmationTarget uses TabManager.windowId cached property without verifying it matches the resolved context.windowId from mainWindowContextForFocusedWorkspaceCloseShortcut, risking sta... Add a fresh read of context.windowId from MainWindowContext instead of relying on TabManager.windowId cache, or update TabManager.windowId before recording and document the freshness guarantee.
Cmux Swiftpm Lockfiles ❌ Error 68 cmux-owned Package.swift files changed without corresponding Package.resolved diffs, violating .github/review-bot-rules/swiftpm-package-resolved.md rule requiring lockfile diffs with package dep... Include all 68 missing package-local Package.resolved diffs with their Package.swift dependency changes, or verify which packages have no dependencies and thus no lockfiles.
Cmux Swift Logging ❌ Error File-scoped Logger in TabManager.swift line 42 violates swift-logging.md: must be declared nonisolated private let when in MainActor context, not just private let. Change line 42 in Sources/TabManager.swift from private let tabManagerLogger = ... to nonisolated private let tabManagerLogger = ... to satisfy MainActor isolation rules.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The PR description covers the key changes (shortcut routing through main-window context, confirmation sheet anchoring, multi-window test) but omits required sections from the template (Testing details, Demo Video, Review Trigger, Checklist). Add the missing template sections: explicit Testing methodology with local verification steps, Demo Video URL if applicable, Review Trigger comment block, and completed Checklist with checkboxes marked.
✅ Passed checks (17 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: fixing window targeting for the Cmd+Shift+W workspace close shortcut.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Swift Actor Isolation ✅ Passed All production code additions are within @MainActor contexts (AppDelegate & TabManager). UITestRecorder is a stateless enum with thread-safe static methods. No implicit MainActor types, shared muta...
Cmux Swift Blocking Runtime ✅ Passed No blocking or timing-based synchronization patterns (sleep, semaphores, locks, or polling) were introduced in production Swift code. New functions use context resolution, logging, and DEBUG-only t...
Cmux Expensive Synchronous Load ✅ Passed PR adds no expensive sync loads to interactive paths; new close-workspace routing methods contain only window resolution/activation logic. Existing close path maintains proper caching with SharedLi...
Cmux No Hacky Sleeps ✅ Passed PR introduces Swift code changes to AppDelegate.swift, TabManager.swift, and UI tests. New TypeScript/JS files (Resources/feed-tui/index.ts) use setTimeout for socket timeouts (with proper cancella...
Cmux Algorithmic Complexity ✅ Passed All new production code operates on fixed-size collections (3 window pointers max) with O(1) complexity. The telemetry function is DEBUG-only and processes the closure-target array only, not all wo...
Cmux Swift Concurrency ✅ Passed The PR introduces minimal DispatchQueue.main.async usage in endCloseConfirmationSession() to defer flag reset after AppKit NSAlert modal dialogs; this is an allowed pattern per the rules for UI iso...
Cmux Swift @Concurrent ✅ Passed All three new synchronous methods in @MainActor-isolated classes (AppDelegate/TabManager) comply with the rule—no missing @concurrent, invalid @concurrent, or async isolation violations.
Cmux Swift File And Package Boundaries ✅ Passed PR adds 66 lines to AppDelegate (17670 total, >800) and 21 lines to TabManager (6193 total), both below the 250-line threshold for oversized files. Changes are focused window-targeting logic and DE...
Cmux User-Facing Error Privacy ✅ Passed No user-facing error privacy violations found. All telemetry recording is DEBUG-only, uses safe identifiers (UUIDs), and follows the review rules for tests/developer-only code.
Cmux Full Internationalization ✅ Passed All production user-facing Swift text uses String(localized:) with matching xcstrings entries; Resources/Localizable.xcstrings includes complete translations for all existing locales; DEBUG-only lo...
Cmux Swiftui State Layout ✅ Passed PR contains no new SwiftUI state management violations. Changes are AppKit shortcut handling (AppDelegate) and DEBUG-only telemetry recording in existing TabManager:ObservableObject. No new @Publis...
Cmux Architecture Rethink ✅ Passed The PR is a small, targeted correctness fix to close-workspace shortcut targeting with clear ownership (mainWindowContextForFocusedWorkspaceCloseShortcut) and invariants (route through event-origin...
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR does not introduce or materially change standalone cmux-owned windows; changes are routing helpers and telemetry refactoring. Lint script confirms pass. DEBUG-only test hook is explicitly allowe...
Cmux Source Artifacts ✅ Passed All three changed files are hand-written source code (AppDelegate.swift, TabManager.swift) and legitimate test code (CloseWorkspacesConfirmDialogUITests.swift). No artifacts, caches, build output,...
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-workspace-close-key-window

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps

greptile-apps Bot commented Jun 17, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes Cmd+Shift+W so it closes the workspace in the focused/key window rather than whatever window the active-manager happened to hold last, and anchors the confirmation sheet to that same window. It adds a new AppDelegate extension for the routing logic, extracts telemetry recording into TabManager+CloseConfirmationTelemetry.swift, and covers the multi-window scenario with a new XCUITest.

  • Shortcut routing (AppDelegate+FocusedWorkspaceCloseShortcut.swift): walks keyWindow → mainWindow → event-window in priority order and activates the resolved window before calling closeCurrentWorkspaceWithConfirmation, ensuring the sheet attaches to the correct window.
  • Telemetry refactor (TabManager+CloseConfirmationTelemetry.swift): moves the inline #if DEBUG UITestRecorder calls to named methods and adds a new recordCloseConfirmationTarget recording; however, the entire file lives in production Sources/ with no release behavior.
  • Test coverage (CloseWorkspacesConfirmDialogUITests): new multi-window test verifies target window ID and sheet host window ID via the recorder JSON, with an improved socket-discovery fallback.

Confidence Score: 4/5

The shortcut-routing fix itself is correct and well-scoped, but the new TabManager+CloseConfirmationTelemetry.swift file placed in production Sources/ is entirely #if DEBUG-guarded test recording with no release behavior — a pattern the repo explicitly prohibits in shipping source.

The window-targeting logic, visibility widenings, and test additions are all sound. The one issue is TabManager+CloseConfirmationTelemetry.swift: it introduces a new file under Sources/ whose entire content is UITestRecorder calls behind #if DEBUG, including the completely new recordCloseConfirmationTarget seam. This is the pattern cmux policy requires to live in a debug folder or test-support module, not in the production source tree.

Sources/TabManager+CloseConfirmationTelemetry.swift — should move to a debug folder or test-support module rather than Sources/.

Important Files Changed

Filename Overview
Sources/AppDelegate+FocusedWorkspaceCloseShortcut.swift New extension routing Cmd+Shift+W through key/main/event-window priority chain before fallback; cleanly factored out of AppDelegate.swift.
Sources/AppDelegate.swift Three helpers widened from private to internal so the new extension file can call them; shortcut dispatch now delegates to closeWorkspaceFromFocusedShortcut.
Sources/TabManager+CloseConfirmationTelemetry.swift New production Sources/ file; entire content is #if DEBUG-guarded UITestRecorder calls with no release behavior — violates no-test-debug-seam-in-production-source rule.
Sources/TabManager.swift Adds calls to the new telemetry helpers at the start of closeWorkspaceWithConfirmation and the multi-workspace close path; removes inline #if DEBUG block.
cmuxUITests/CloseWorkspacesConfirmDialogUITests.swift Adds testCmdShiftWTargetsFocusedWindowWorkspaceWhenMultipleWindowsAreOpen; improves socket discovery fallback path and adds single-workspace cancel helpers.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["Cmd+Shift+W pressed"] --> B["matchConfiguredShortcut(.closeWorkspace)"]
    B --> C["closeWorkspaceFromFocusedShortcut(event:)"]
    C --> D["mainWindowContextForFocusedWorkspaceCloseShortcut(event:)"]
    D --> E{NSApp.keyWindow is cmux window?}
    E -- yes --> F["Use keyWindow context"]
    E -- no --> G{NSApp.mainWindow is cmux window?}
    G -- yes --> H["Use mainWindow context"]
    G -- no --> I["mainWindowContext(forShortcutEvent:)"]
    I --> J{Found context?}
    J -- yes --> K["Use event-derived context"]
    J -- no --> L{shortcutEventHasAddressableWindow?}
    L -- yes & cmuxWindowShouldOwnClose --> M["preferredMainWindowContextForShortcutRouting"]
    L -- no / not cmux --> N["return nil → no-op"]
    F --> O["setActiveMainWindow / activateMainWindowContext"]
    H --> O
    K --> O
    M --> O
    O --> P["tabManager.closeCurrentWorkspaceWithConfirmation()"]
    P --> Q["recordCloseConfirmationTarget (#if DEBUG only)"]
    P --> R["presentAlert on closeConfirmationPresentingWindow"]
    R --> S{presentation}
    S -- sheet --> T["recordCloseConfirmationSheetPresentation (#if DEBUG only)"]
    S -- appModal --> U["recordCloseConfirmationAppModalPresentation (#if DEBUG only)"]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A["Cmd+Shift+W pressed"] --> B["matchConfiguredShortcut(.closeWorkspace)"]
    B --> C["closeWorkspaceFromFocusedShortcut(event:)"]
    C --> D["mainWindowContextForFocusedWorkspaceCloseShortcut(event:)"]
    D --> E{NSApp.keyWindow is cmux window?}
    E -- yes --> F["Use keyWindow context"]
    E -- no --> G{NSApp.mainWindow is cmux window?}
    G -- yes --> H["Use mainWindow context"]
    G -- no --> I["mainWindowContext(forShortcutEvent:)"]
    I --> J{Found context?}
    J -- yes --> K["Use event-derived context"]
    J -- no --> L{shortcutEventHasAddressableWindow?}
    L -- yes & cmuxWindowShouldOwnClose --> M["preferredMainWindowContextForShortcutRouting"]
    L -- no / not cmux --> N["return nil → no-op"]
    F --> O["setActiveMainWindow / activateMainWindowContext"]
    H --> O
    K --> O
    M --> O
    O --> P["tabManager.closeCurrentWorkspaceWithConfirmation()"]
    P --> Q["recordCloseConfirmationTarget (#if DEBUG only)"]
    P --> R["presentAlert on closeConfirmationPresentingWindow"]
    R --> S{presentation}
    S -- sheet --> T["recordCloseConfirmationSheetPresentation (#if DEBUG only)"]
    S -- appModal --> U["recordCloseConfirmationAppModalPresentation (#if DEBUG only)"]
Loading

Reviews (9): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile

Comment on lines +399 to +415
private func workspaceIds(inWindow windowId: String) -> [String]? {
guard socketCommand("focus_window \(windowId)") == "OK",
let response = socketCommand("list_workspaces") else {
return nil
}
if response == "No workspaces" {
return []
}
return response
.split(separator: "\n")
.compactMap { line in
line
.split(whereSeparator: { $0 == " " || $0 == "\t" })
.map(String.init)
.first(where: { UUID(uuidString: $0) != nil })
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 workspaceIds sends focus_window as a side effect during polling

workspaceIds(inWindow:) issues a focus_window socket command before list_workspaces every time it is called. Because waitForWorkspace polls this predicate repeatedly (up to its timeout), the app's focused-window state is mutated on every predicate iteration. The two sequential waitForWorkspace calls at the end of the test — one for focusedWindowId and one for otherWindowId — will alternate sending focus_window to each window until both settle. While harmless for this specific test (both windows remain open throughout polling), any future test that calls waitForWorkspace while relying on a stable focused window, or while an action is in progress on the currently-focused window, could trigger unexpected behavior or race conditions in the app under test.

Comment on lines +368 to +384
}

private func keyWindowId() -> String? {
guard let response = socketCommand("list_windows") else { return nil }
for line in response.split(separator: "\n") {
let parts = line
.trimmingCharacters(in: .whitespacesAndNewlines)
.split(separator: " ")
.map(String.init)
guard parts.first == "*", parts.count >= 3 else { continue }
return parts[2]
}
return nil
}

private func waitForWorkspace(
_ workspaceId: String,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 keyWindowId() depends on a hardcoded field-position assumption in list_windows output

keyWindowId() parses the response from list_windows by checking that the first token is "*" and reading the window ID from parts[2] (the third space-split field). If the output format changes — for example, if the * marker is removed, or the window ID moves to a different position — this silently returns nil on every iteration, causing waitForKeyWindow to always time out. The test then invokes app.typeKey("w", modifierFlags: [.command, .shift]) on whatever window happens to be focused rather than the intended focusedWindowId, potentially masking the regression the test is intended to catch.

@azooz2003-bit
azooz2003-bit force-pushed the feat-workspace-close-key-window branch 4 times, most recently from 7b1c500 to a31e19f Compare June 18, 2026 00:08
@azooz2003-bit
azooz2003-bit force-pushed the feat-workspace-close-key-window branch from a31e19f to bdc2c88 Compare June 18, 2026 00:12
@azooz2003-bit
azooz2003-bit force-pushed the feat-workspace-close-key-window branch from bdc2c88 to 7513f14 Compare June 18, 2026 00:19

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Sources/AppDelegate.swift`:
- Around line 6288-6305: The comment about auxiliary cmux windows on lines
6291-6292 is currently placed in the wrong branch. It describes behavior for
windows that should NOT own the close shortcut (auxiliary windows), but it is
located in the branch that handles windows that SHOULD own it (when
cmuxWindowShouldOwnCloseShortcut returns true). Move this comment to the else
branch (where the nil return happens) to correctly document the auxiliary window
case, or relocate it before the outer if statement for the
shortcutEventHasAddressableWindow check to provide overall context for the logic
flow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: e58d2c3e-ff4c-43ff-88f1-55eb42b17ec6

📥 Commits

Reviewing files that changed from the base of the PR and between a31e19f and bdc2c88.

📒 Files selected for processing (2)
  • Sources/AppDelegate.swift
  • Sources/TabManager.swift

Comment thread Sources/AppDelegate.swift Outdated
Comment on lines +6288 to +6305
if shortcutEventHasAddressableWindow(event) {
if let eventWindow = resolvedShortcutEventWindow(event),
cmuxWindowShouldOwnCloseShortcut(eventWindow) {
// Auxiliary cmux windows do not own workspaces. Preserve their existing
// app-shortcut behavior by delegating to the focused main window below.
} else {
#if DEBUG
logWorkspaceCreationRouting(
phase: "choose",
source: "shortcut.closeWorkspace",
reason: "event_context_required_no_fallback",
event: event,
chosenContext: nil
)
#endif
return nil
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Comment placement reduces readability of the guard logic.

The comment on lines 6291-6292 describes auxiliary window behavior but is placed in the branch that executes when cmuxWindowShouldOwnCloseShortcut(eventWindow) returns true—i.e., for windows that should own the shortcut (main terminal windows). The actual auxiliary-window case is the else branch that returns nil.

Consider moving the rationale comment before the outer if or adding a brief inline comment in the else branch:

Suggested clarification
+        // Auxiliary cmux windows do not own workspaces. When the shortcut originates
+        // from such a window, we check if it should delegate to the active manager.
         if shortcutEventHasAddressableWindow(event) {
             if let eventWindow = resolvedShortcutEventWindow(event),
                cmuxWindowShouldOwnCloseShortcut(eventWindow) {
-                // Auxiliary cmux windows do not own workspaces. Preserve their existing
-                // app-shortcut behavior by delegating to the focused main window below.
+                // Main terminal window—fall through to active-manager fallback.
             } else {
+                // Auxiliary window or unresolvable—do not perform close action.
 `#if` DEBUG
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if shortcutEventHasAddressableWindow(event) {
if let eventWindow = resolvedShortcutEventWindow(event),
cmuxWindowShouldOwnCloseShortcut(eventWindow) {
// Auxiliary cmux windows do not own workspaces. Preserve their existing
// app-shortcut behavior by delegating to the focused main window below.
} else {
#if DEBUG
logWorkspaceCreationRouting(
phase: "choose",
source: "shortcut.closeWorkspace",
reason: "event_context_required_no_fallback",
event: event,
chosenContext: nil
)
#endif
return nil
}
}
// Auxiliary cmux windows do not own workspaces. When the shortcut originates
// from such a window, we check if it should delegate to the active manager.
if shortcutEventHasAddressableWindow(event) {
if let eventWindow = resolvedShortcutEventWindow(event),
cmuxWindowShouldOwnCloseShortcut(eventWindow) {
// Main terminal window—fall through to active-manager fallback.
} else {
// Auxiliary window or unresolvable—do not perform close action.
`#if` DEBUG
logWorkspaceCreationRouting(
phase: "choose",
source: "shortcut.closeWorkspace",
reason: "event_context_required_no_fallback",
event: event,
chosenContext: nil
)
`#endif`
return nil
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/AppDelegate.swift` around lines 6288 - 6305, The comment about
auxiliary cmux windows on lines 6291-6292 is currently placed in the wrong
branch. It describes behavior for windows that should NOT own the close shortcut
(auxiliary windows), but it is located in the branch that handles windows that
SHOULD own it (when cmuxWindowShouldOwnCloseShortcut returns true). Move this
comment to the else branch (where the nil return happens) to correctly document
the auxiliary window case, or relocate it before the outer if statement for the
shortcutEventHasAddressableWindow check to provide overall context for the logic
flow.

@azooz2003-bit
azooz2003-bit force-pushed the feat-workspace-close-key-window branch 2 times, most recently from cd51e00 to 977d1ab Compare June 18, 2026 00:28
@lawrencecchen lawrencecchen added the stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening. label Sep 23, 2026
@github-project-automation github-project-automation Bot moved this from Todo to Done in cmux backlog Sep 23, 2026

This branch was successfully deployed

1 active deployment
Preview – cmux — 556c873a Deployed Jun 21, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants